package cn.dinxian.activiti.demo2.config;

import org.activiti.engine.ManagementService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.impl.RuntimeServiceImpl;
import org.activiti.engine.impl.db.DbSqlSession;
import org.activiti.engine.impl.interceptor.Command;
import org.activiti.engine.impl.interceptor.CommandContext;
import org.activiti.engine.impl.interceptor.CommandExecutor;
import org.activiti.engine.impl.persistence.entity.JobEntity;

import org.activiti.engine.runtime.Job;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.Date;

/**
 * Created by ct on 2016/10/23 0023.
 */
@Component
public class UpdateTimerService {

    @Autowired
    private RuntimeService runtimeService;

    //通过CommandExecutor.execute 命令执行器 执行命令
    // UpdateTimerCommand(timerEntity) 是一个继承了Command的类 
    public void executeUpdate(JobEntity timerEntity){
        RuntimeServiceImpl rsi  = (RuntimeServiceImpl)runtimeService;
        CommandExecutor commandExecutor = rsi.getCommandExecutor();
        commandExecutor.execute(new UpdateTimerCommand(timerEntity));
    }

    //JobEntity方法 实体 工具 用来配置命令
    public void modifyDuedate(Job job,Date duedate){
        if (job != null) {
            if (job instanceof JobEntity) {
                JobEntity timer = (JobEntity) job;
                timer.setDuedate(duedate);
                executeUpdate(timer);
            }
        }
    }

/*
* 
* 创建一个修改定时器的命令,实现Command接口，泛型为TimerEntity，表示该命令执行对TimerEntity（对应act_ru_job表）的操作。在execute方法中，
* 获取到DbSqlSession，继而得到具体执行的statement,通过调用sqlSession的udpate方法，执行更新。
  
  * 添加或者执行命令 需要继承command 接口注入对一的泛型
* */
    //命令载体  传入命令在其中配置命令如何执行
    private final class UpdateTimerCommand implements Command<JobEntity> {
        private final JobEntity timerEntity;
        //修改命令就是对 entity实体的修改
        public UpdateTimerCommand(JobEntity timerEntity) {
            this.timerEntity = timerEntity;
        }
        
        //命令的执行中 可通过传入的CommandContext（命令执行上下文）获得DbSqlSession
        // 通过dbsqlSession（sql会话）的getUpdateStatement 获得命令对应的sql语句      来获得执行的语句
        //执行更新
        @Override
        public JobEntity execute(CommandContext commandContext) {
            DbSqlSession dbsqlSession = commandContext.getDbSqlSession();
            String statement = dbsqlSession.getDbSqlSessionFactory()
                    .getUpdateStatement(timerEntity);
            dbsqlSession.getSqlSession().update(statement, timerEntity);
            return timerEntity;
        }
    }
}